<!--
 * 歌曲页面
 *
 * @Author: Reisen
 * @Date: 2025-11-26
-->
<template>
  <div class="table">
    <div class="crumbs" style="padding: 20px 0 5px 20px">
      <i class="iconfont icon-song-manage-button" style="font-size: 15px">
        歌曲信息</i
      >
    </div>
    <div class="container">
      <div class="handle-box">
        <el-input
          v-model="select_word"
          placeholder="请输入歌曲名"
          class="handle-input"
        ></el-input
        ><br /><br />
        <el-button type="danger" size="small" style="font-size: 14px" @click="delAll"
        ><i
          class="iconfont icon-delete-button"
          style="font-size: 15px"
        ></i>
          批量删除</el-button
        >
        <el-button
          type="primary"
          size="small"
          style="font-size: 14px"
          @click="centerDialogVisible = true"
        ><i class="iconfont icon-add-button" style="font-size: 15px"></i>
          添加歌曲</el-button
        >
      </div>
    </div>
    <el-table
      ref="multipleTable"
      border
      style="width: 100%"
      height="680px"
      :data="data"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="40"></el-table-column>
      <el-table-column label="歌曲图片" width="110" align="center">
        <template slot-scope="scope">
          <div class="song-img">
            <img :src="getUrl(scope.row.pic)" style="width: 100%" />
          </div>
          <div
            class="play"
            @click="setSongUrl(scope.row.url, scope.row.name)"
          >
            <div v-if="toggle == scope.row.name">
              <svg class="icon">
                <use xlink:href="#icon-zanting"></use>
              </svg>
            </div>
            <div v-if="toggle != scope.row.name">
              <svg class="icon">
                <use xlink:href="#icon-bofanganniu"></use>
              </svg>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column
        prop="name"
        label="歌手-歌名"
        width="120"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="introduction"
        label="专辑"
        width="150"
        align="center"
      ></el-table-column>
      <el-table-column label="歌词" align="center">
        <template slot-scope="scope">
          <ul style="height: 100px; overflow: scroll">
            <li
              v-for="(item, index) in parseLyric(scope.row.lyric)"
              :key="index"
            >
              {{ item }}
            </li>
          </ul>
        </template>
      </el-table-column>
      <el-table-column label="资源更新" align="center" width="100">
        <template slot-scope="scope">
          <el-upload
            :action="uploadUrl(scope.row.id)"
            :before-upload="beforeAvatorUpload"
            :on-success="handleAvatorSuccess"
          >
            <el-button size="mini">更新图片</el-button>
          </el-upload>
          <br />
          <el-upload
            :action="uploadSongUrl(scope.row.id)"
            :before-upload="beforeSongUpload"
            :on-success="handleSongSuccess"
          >
            <el-button size="mini">更新歌曲</el-button>
          </el-upload>
        </template>
      </el-table-column>

      <el-table-column label="操作" width="250" align="center" fixed="right">
        <template slot-scope="scope">
          <el-button type="success" @click="handleEdit(scope.row)" style="font-size: 18px;"
          ><i class="iconfont icon-r-edit" style="font-size: 22px"></i> 编辑</el-button
          >
          <el-button
            type="danger"
            @click="handleDelete(scope.row.id)" style="font-size: 18px;"
          ><i class="iconfont icon-r-add" style="font-size: 22px"></i> 删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination">
      <el-pagination
        background
        layout="total,prev,pager,next"
        :current-page="currentPage"
        :page-size="pageSize"
        :total="tableData.length"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>

    <el-dialog
      title="添加歌曲"
      :visible.sync="centerDialogVisible"
      width="400px"
      center
    >
      <el-form
        :model="registerForm"
        ref="registerForm"
        label-width="80px"
        action=""
        id="tf"
      >
        <div>
          <label>歌曲上传</label>
          <input type="file" name="file" id="songFileInput" accept="audio/mpeg,audio/wav,audio/ogg,audio/flac" />
        </div>
      </el-form>
      <span slot="footer">
                <el-button size="mini" @click="centerDialogVisible = false"
                >取消</el-button
                >
                <el-button size="mini" @click="addSong">确定</el-button>
            </span>
    </el-dialog>

    <el-dialog
      title="修改歌曲"
      :visible.sync="editVisible"
      width="400px"
      center
    >
      <el-form :model="form" ref="form" label-width="80px">
        <el-form-item prop="name" label="歌手-歌名" size="mini">
          <el-input
            v-model="form.name"
            placeholder="歌手-歌名"
          ></el-input>
        </el-form-item>
        <el-form-item prop="introduction" label="专辑" size="mini">
          <el-input
            v-model="form.introduction"
            placeholder="专辑"
          ></el-input>
        </el-form-item>
        <el-form-item prop="lyric" label="歌词" size="mini">
          <el-input
            v-model="form.lyric"
            placeholder="歌词"
            type="textarea"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer">
                <el-button size="mini" @click="editVisible = false"
                >取消</el-button
                >
                <el-button size="mini" @click="editSave">确定</el-button>
            </span>
    </el-dialog>

    <el-dialog
      title="删除歌曲"
      :visible.sync="delVisible"
      width="300px"
      center
    >
      <div align="center">删除不可恢复，是否确定删除？</div>
      <span slot="footer">
                <el-button size="mini" @click="delVisible = false"
                >取消</el-button
                >
                <el-button size="mini" @click="deleteRow">确定</el-button>
            </span>
    </el-dialog>
  </div>
</template>


<script>
import { mixin } from "../mixins/index";
import { mapGetters } from "vuex";
import "@/assets/js/iconfont.js";
import { songOfSingerId, updateSong, delSong } from "../api/index";
import axios from 'axios';

export default {
  mixins: [mixin],
  data() {
    return {
      singerId: "", //歌手id
      singerName: "", //歌手名
      centerDialogVisible: false, //添加弹窗是否显示
      editVisible: false, //编辑弹窗是否显示
      delVisible: false, //删除弹窗是否显示
      registerForm: {
        //添加框
        name: "",
        singerName: "",
        introduction: "",
        lyric: "",
      },
      form: {
        //编辑框
        id: "",
        name: "",
        introduction: "",
        lyric: "",
      },
      tableData: [],
      tempData: [],
      select_word: "",
      pageSize: 5, //分页每页大小
      currentPage: 1, //当前页
      idx: -1, //当前选择项
      multipleSelection: [], //哪些项已经打勾
      toggle: false, //播放器的图标状态
    };
  },
  computed: {
    ...mapGetters(["isPlay"]),
    //计算当前搜索结果表里的数据
    data() {
      return this.tableData.slice(
        (this.currentPage - 1) * this.pageSize,
        this.currentPage * this.pageSize
      );
    },
  },
  watch: {
    //搜索框里面的内容发生变化的时候，搜索结果table列表的内容跟着它的内容发生变化
    select_word: function () {
      if (this.select_word == "") {
        this.tableData = this.tempData;
      } else {
        this.tableData = [];
        for (let item of this.tempData) {
          if (item.name.includes(this.select_word)) {
            this.tableData.push(item);
          }
        }
      }
    },
  },
  created() {
    this.singerId = this.$route.query.id;
    if (!this.singerId) {
      this.singerId = 0;
    }
    this.singerName = this.$route.query.name;
    this.getData();
  },
  destroyed() {
    this.$store.commit("setIsPlay", false);
  },
  methods: {
    //获取当前页
    handleCurrentChange(val) {
      this.currentPage = val;
    },
    //查询所有歌手
    getData() {
      this.tempData = [];
      this.tableData = [];
      songOfSingerId(this.singerId).then((res) => {
        this.tempData = res;
        this.tableData = res;
        this.currentPage = 1;
      });
    },
    //添加歌手
    addSong() {
      let _this = this;
      var formData = new FormData(document.getElementById("tf"));

      // 优化：通过唯一ID获取文件输入元素
      const fileInput = document.getElementById("songFileInput");
      if (!fileInput) {
        _this.notify('未找到文件输入元素，请检查HTML结构', 'error');
        console.error('文件输入元素未找到，请检查HTML中的ID是否正确');
        return;
      }

      // 检查文件是否已选择
      if (!fileInput.files || fileInput.files.length === 0) {
        _this.notify('请选择要上传的歌曲文件', 'warning');
        return;
      }

      const file = fileInput.files[0];

      // 优化：使用更灵活的文件类型校验方式
      const validTypes = ['audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/flac'];
      const fileType = file.type;
      const fileName = file.name;
      const fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();

      // 检查文件类型（同时校验MIME类型和扩展名）
      if (!validTypes.includes(fileType) && fileExtension !== 'flac') {
        _this.notify('请上传MP3、WAV、OGG或FLAC格式的音频文件', 'warning');
        return;
      }

      // 检查文件大小
      const fileSize = file.size / 1024 / 1024; // 转换为MB
      if (fileSize > 50) { // 限制文件大小为50MB
        _this.notify(`文件大小超过限制：${fileSize.toFixed(2)}MB，最大允许50MB`, 'warning');
        return;
      }

      console.log('准备上传文件:', fileName, '大小:', fileSize.toFixed(2) + 'MB', '类型:', fileType);

      // 设置表单数据
      formData.append("singerId", this.singerId);
      formData.set("name", formData.get("name") ? this.singerName + "-" + formData.get("name") : this.singerName + "-未命名");
      if (!formData.get("lyric")) {
        formData.set("lyric", "[00:00:00]暂无歌词");
      }

      // 使用新的方法上传，尝试直接访问song-service
      this.uploadFile(formData, file);
    },

    // 增加新方法：专门处理文件上传
    uploadFile(formData, file) {
      let _this = this;

      // 显示加载提示
      this.$message({
        message: '正在上传歌曲，请稍候...',
        type: 'info'
      });

      // 创建一个新的XMLHttpRequest
      const xhr = new XMLHttpRequest();

      // 设置超时时间更长
      xhr.timeout = 300000; // 5分钟超时

      // 监听上传进度
      xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
          const percentComplete = (e.loaded / e.total) * 100;
          console.log('上传进度:', percentComplete.toFixed(2) + '%');
        }
      };

      // 配置请求 - 尝试直接连接到song-service而不是通过网关
      // 这是为了排除网关转发大文件的问题
      // 注意：这里应该根据实际情况选择合适的地址
      const uploadUrl = 'http://localhost:8082/song/song/add';
      console.log('上传URL:', uploadUrl);

      xhr.open('POST', uploadUrl, true);
      xhr.withCredentials = true; // 允许发送凭证

      xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const response = JSON.parse(xhr.responseText);
            console.log('上传响应:', response);
            if (response.code === 1 || response.code === 0) { // 兼容不同的成功代码
              _this.getData();
              _this.registerForm = {};
              // 重置文件输入，解决重复选择同一文件时不触发change事件的问题
              fileInput.value = '';
              _this.notify(response.msg || '上传成功', 'success');
            } else {
              _this.notify(response.msg || '保存失败', 'error');
            }
          } catch (e) {
            console.error('解析响应失败:', e, xhr.responseText);
            _this.notify('服务器返回数据解析失败', 'error');
          }
        } else {
          console.error('上传失败，状态码:', xhr.status, xhr.statusText);
          _this.notify('上传失败: HTTP ' + xhr.status, 'error');
        }
        _this.centerDialogVisible = false;
      };

      xhr.onerror = function() {
        console.error('网络错误，可能原因：',
          '1. 服务器未运行',
          '2. 服务器拒绝连接',
          '3. 网络问题',
          '4. 服务器内部错误'
        );
        // 尝试使用备用地址
        _this.fallbackUpload(formData, file);
      };

      xhr.ontimeout = function() {
        console.error('请求超时');
        _this.notify('上传超时，请检查网络或减小文件大小', 'error');
        _this.centerDialogVisible = false;
      };

      // 发送请求
      try {
        xhr.send(formData);
      } catch (error) {
        console.error('发送请求失败:', error);
        _this.notify('发送请求失败: ' + error.message, 'error');
        _this.centerDialogVisible = false;
      }
    },

    // 添加备用上传方法
    fallbackUpload(formData, file) {
      let _this = this;
      console.log('尝试备用上传方式...');

      const xhr = new XMLHttpRequest();
      xhr.timeout = 300000; // 5分钟超时

      xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
          const percentComplete = (e.loaded / e.total) * 100;
          console.log('备用上传进度:', percentComplete.toFixed(2) + '%');
        }
      };

      // 尝试使用网关地址
      xhr.open('POST', 'http://localhost:9171/song/song/add', true);
      xhr.withCredentials = true;

      xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const response = JSON.parse(xhr.responseText);
            console.log('上传响应:', response);
            if (response.code === 1 || response.code === 0) {
              _this.getData();
              _this.registerForm = {};
              // 重置文件输入
              document.getElementById("songFileInput").value = '';
              _this.notify(response.msg || '上传成功', 'success');
            } else {
              _this.notify(response.msg || '保存失败', 'error');
            }
          } catch (e) {
            console.error('解析响应失败:', e, xhr.responseText);
            _this.notify('服务器返回数据解析失败', 'error');
          }
        } else {
          console.error('备用上传失败，状态码:', xhr.status);
          _this.notify('上传失败: HTTP ' + xhr.status, 'error');
        }
        _this.centerDialogVisible = false;
      };

      xhr.onerror = function() {
        console.error('备用上传也失败，请检查服务器状态');
        _this.notify('无法连接到服务器，请确认服务器是否正常运行', 'error');
        _this.centerDialogVisible = false;
      };

      xhr.ontimeout = function() {
        console.error('备用上传超时');
        _this.notify('上传超时，请检查网络或减小文件大小', 'error');
        _this.centerDialogVisible = false;
      };

      try {
        xhr.send(formData);
      } catch (error) {
        console.error('备用上传发送失败:', error);
        _this.notify('无法发送请求: ' + error.message, 'error');
        _this.centerDialogVisible = false;
      }
    },
    //弹出编辑页面
    handleEdit(row) {
      this.editVisible = true;
      this.form = {
        id: row.id,
        name: row.name,
        introduction: row.introduction,
        lyric: row.lyric,
      };
    },
    //保存编辑页面修改的数据
    editSave() {
      let params = new URLSearchParams();
      params.append("id", this.form.id);
      params.append("name", this.form.name);
      params.append("introduction", this.form.introduction);
      params.append("lyric", this.form.lyric);

      updateSong(params)
        .then((res) => {
          if (res.code == 1) {
            this.getData();
            this.notify("修改成功", "success");
          } else {
            this.notify("修改失败", "error");
          }
        })
        .catch((err) => {
          console.log(err);
        });
      this.editVisible = false;
    },
    //更新图片
    uploadUrl(id) {
      return `${this.$store.state.HOST}/song/song/updateSongPic?id=${id}`;
    },
    //删除一名歌手
    deleteRow() {
      delSong(this.idx)
        .then((res) => {
          if (res) {
            this.getData();
            this.notify("删除成功", "success");
          } else {
            this.notify("删除失败", "error");
          }
        })
        .catch((err) => {
          console.log(err);
        });
      this.delVisible = false;
    },
    //解析歌词
    parseLyric(text) {
      let lines = text.split("\n");
      let pattern = /\[\d{2}:\d{2}.(\d{3}|\d{2})\]/g;
      let result = [];
      for (let item of lines) {
        let value = item.replace(pattern, "");
        result.push(value);
      }
      return result;
    },
    //上传歌曲之前的校验（支持FLAC格式）
    beforeSongUpload(file) {
      var fileExtension = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
      if (fileExtension !== 'mp3' && fileExtension !== 'flac') {
        this.$message({
          message: "上传文件只能是MP3或FLAC格式",
          type: "error",
        });
        return false;
      }
      return true;
    },
    //上传歌曲成功之后要做的工作
    handleSongSuccess(res) {
      let _this = this;
      if (res.code == 1) {
        _this.getData();
        _this.$notify({
          title: "上传成功",
          type: "success",
        });
      } else {
        _this.$notify({
          title: "上传失败",
          type: "error",
        });
      }
    },
    //更新歌曲url
    uploadSongUrl(id) {
      return `${this.$store.state.HOST}/song/song/updateSongUrl?id=${id}`;
    },
    //切换播放歌曲
    setSongUrl(url, name) {
      this.toggle = name;
      this.$store.commit("setUrl", this.$store.state.HOST + url);
      if (this.isPlay) {
        this.$store.commit("setIsPlay", false);
      } else {
        this.$store.commit("setIsPlay", true);
      }
    },
  },
};
</script>




<style scoped>
.handle-box {
  margin-bottom: 20px;
}
.song-img {
  width: 100%;
  height: 80px;
  border-radius: 5px;
  margin-bottom: 5px;
  overflow: hidden;
}
.handle-input {
  width: 300px;
  display: inline-block;
}
.pagination {
  display: flex;
  justify-content: center;
}
.play {
  position: absolute;
  z-index: 100;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  top: 18px;
  left: 15px;
}

.icon {
  width: 2em;
  height: 2em;
  color: white;
  fill: currentColor;
  overflow: hidden;
}
</style>
